package com.auth.manager.security.auth;

import com.auth.manager.pojo.sys.SysRole;
import com.auth.manager.service.sys.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @version 1.0.0
 * @Date: 2022/4/27 16:46
 * @Author ZhuYouBin
 * @Description [用户授权],主要作用是从数据库中获取所有url对应的用户角色映射关系,然后交给Spring Security去进行权限判断
 */
@Component
public class AuthMetaSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private SysRoleService sysRoleService;

    // 这个方法就是从数据库查询所有的url对应的访问角色
    // 可以放入 Redis 缓存, 之后可以从缓存中获取, 提高效率
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        /**
         * 这个方法主要的逻辑是什么呢？？？
         * 1、从数据库查询当前url对应的访问角色
         * 2、如果当前url存在数据库里面，则返回url对应的角色标识
         * 3、如果当前url不在数据库里面，则返回一个自定义的角色标识
         */
        // 1、获取当前请求url
        FilterInvocation request = (FilterInvocation) object;
        String requestUrl = request.getRequestUrl();
        // 去掉请求url参数
        if (requestUrl.contains("?")) {
            requestUrl = requestUrl.substring(0, requestUrl.lastIndexOf("?"));
        }

        // 2、根据 url 查询数据库对应的角色
        // TODO 可以从 Redis 缓存里面获取
        List<SysRole> sysRoleList = sysRoleService.queryAllRoleAndUrl();
        if (!CollectionUtils.isEmpty(sysRoleList)) {
            List<String> roleLists = new ArrayList<>();
            final String tempUrl = requestUrl;
            sysRoleList.forEach(sysRole -> {
                if (tempUrl.contains(sysRole.getUrl())) {
                    roleLists.add(sysRole.getRoleKey());
                }
            });
            return SecurityConfig.createList(roleLists.toArray(new String[0]));
        }

        // 3、url不存在,则返回默认角色标识
        return SecurityConfig.createList("ROLE_login");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return new ArrayList<>();
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
